home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / bnce_ra.exe / BOUNCE.C next >
C/C++ Source or Header  |  1989-04-04  |  9KB  |  378 lines

  1.  /* bounce.c - bouncing ball
  2.  by: R. Abramson, CIS ID 74676,3345
  3.  Usage: bounce [/b] [/c] [/L] [delay]
  4.  where: /b = show border, delay = integer less than 32768, /c = show color
  5.     /L = no bottom line legend
  6.  Delays needed to slow down display on an AT
  7.  EXAMPLE -> bounce /b 8000
  8.  kbd controls
  9.     0 - top speed
  10.     9 - slow speed (8000)
  11.     f - speed x2
  12.     s - speed /2
  13.     b - border on
  14.     c - border off
  15.     l - kill bottom legend
  16.     L - restore bottom legend
  17.     1 - expand
  18.     2 - shrink
  19.     a - add a ball
  20.     A - remove a ball
  21.     g - shoot gun
  22.     Esc - Quit
  23.  If you want to recompile:
  24.  1. Written in MS QC ver 1.0.  Medium model.
  25.  2. To compile, requires bounce.c, video.h AND EITHER video.c or video.obj
  26.  3. NOTE - needs 8K stack, as in -> link bounce video /stack:8912
  27. */
  28. #include <memory.h>
  29. #include <stdio.h>
  30. #include <dos.h>
  31. #include <conio.h>
  32. #include <stdlib.h>
  33. #include <bios.h>
  34. #include <string.h>
  35. #include "video.h"
  36.  
  37. #define BOOL int
  38. #define TRUE 1
  39. #define FALSE 0
  40. #define W 80 /* screenwidth */
  41. #define MAXBALLS 8
  42.  
  43. /* possible object trajectories */
  44. #define Se 1
  45. #define Ne 2
  46. #define Nw 3
  47. #define Sw 4
  48.  
  49. /* an 'object' */
  50. typedef struct {
  51.     int h;  /* dimensions */
  52.     int w;
  53.     int x0; /* last pos */
  54.     int y0;
  55.     int x;  /* current pos */
  56.     int y;
  57.     int xn; /* next pos */
  58.     int yn;
  59.     int t;  /* trajectory */
  60.     int v;  /* velocity */
  61.     char d[200];  /* pattern data */
  62. } object_t;
  63.  
  64. static char ball[] = {
  65.          (char)219,(char)219,(char)219,(char)219,
  66.          (char)219,(char)219,(char)219,(char)219
  67. };
  68.  
  69. int main( int argc, char **argv );
  70. void o_put( object_t *o, object_t *h, vid_rec *v );
  71. void o_unput( object_t *h, object_t *o, vid_rec *v );
  72. void o_clr( object_t *o, vid_rec *v );
  73. void delay( int t );
  74. void do_botleg( char *botleg, vid_rec *v );
  75. void calc_next( object_t *o );
  76.  
  77. int main( int argc, char **argv )
  78. {
  79.     int i, t = 8000, jx = 1, numballs = 1, j;
  80.     object_t o[MAXBALLS], h[MAXBALLS + 1], bullet;
  81.     char ch = 0;
  82.     vid_rec v0, v;
  83.     char scr_buf[4000];
  84.     unsigned num;
  85.     BOOL color_flag = FALSE, bor_flag = TRUE, bot_flag = TRUE;
  86.     static char botleg[] = " Border b/c   Add Balls a/A   Speed 9/0/f/s   Size 1/2   Line l/L  Gun g [Esc]";
  87.  
  88.     /* parse command line... */
  89.     for ( i = 1; i < argc; i++ ) {
  90.         if ( strcmp(argv[i], "/c") == 0 ) color_flag = TRUE;
  91.         if ( strcmp(argv[i], "/b") == 0 ) bor_flag = TRUE;
  92.         if ( strcmp(argv[i], "/L") == 0 ) bot_flag = FALSE;
  93.         if ( 0 != atoi(argv[i]) ) t = atoi( argv[i] );
  94.     }
  95.  
  96.     /* init the videos */
  97.     v0.mode = get_vid_mode();
  98.     v0.page = get_vid_page();
  99.     v.page = v0.page;
  100.     v.EQUIP_FLAG = (_bios_equiplist() & (unsigned) 0x0030) >> 4;
  101.     if ( v.EQUIP_FLAG == 3 ) {
  102.         v.VIDEO_SEG = 0xb000; /* MONO, HERC */
  103.         v0.VIDEO_SEG = 0xb000;
  104.         v.mode = 7; /* if mono, we'll use mode 7 */
  105.     }
  106.     else {
  107.         v.VIDEO_SEG = 0xb800; /* CGA OR ANY OTHER DISPLAY */
  108.         v0.VIDEO_SEG = 0xb800;
  109.         /* if not mono, we'll use mode 2 or 3 */
  110.         if ( color_flag )
  111.             v.mode = 3;
  112.         else
  113.             v.mode = 2;
  114.     }
  115.     num = crsr_pos_get( v0.page );
  116.     v0.crsr_col = (char) (num & 0x00ff);
  117.     v0.crsr_row = (char)( num/256 );
  118.     scr_save( &v0, scr_buf );
  119.  
  120.     /* clear up our screen */
  121.     crsr_pos_hide( v.page );
  122.     cl_scr( &v );
  123.     if ( bot_flag ) do_botleg( botleg, &v );
  124.     if ( bor_flag ) bor_wndw( 0, 0, 23, W-1, &v );
  125.  
  126.     for ( i = 0; i < MAXBALLS; i++ ) {
  127.         o[i].h = jx;
  128.         o[i].w = 2*jx;
  129.         memset( o[i].d, (char) 219, sizeof( o[i].d ) );
  130.         o[i].x = 1 + i*(W-1)/MAXBALLS;
  131.         o[i].y = 2 + i*23/MAXBALLS;
  132.         o[i].t = 1 + (i % 4);
  133.         o[i].v = i + 1;
  134.     }
  135.     bullet.h = 1;
  136.     bullet.w = 1;
  137.     bullet.x = 38;
  138.     bullet.y = 24;
  139.     bullet.d[0] = (char) 4;
  140.     while ( ch != 27 ) {
  141.         if ( kbhit() ) {
  142.             ch = (char) getch();
  143.             switch ( ch ) {
  144.                 case 'f':
  145.                     t /= 2;
  146.                     break;
  147.                 case 's':
  148.                     if ( t == 0 ) t = 1; else t *= 2;
  149.                     break;
  150.                 case '0':
  151.                     t = 0;
  152.                     break;
  153.                 case '9':
  154.                     t = 8000;
  155.                     break;
  156.                 case 'b':
  157.                     bor_wndw( 0, 0, 23, W-1, &v );
  158.                     bor_flag = TRUE;
  159.                     break;
  160.                 case 'c':
  161.                     bor_flag = FALSE;
  162.                     cl_scr ( &v );
  163.                     if ( bot_flag ) do_botleg( botleg, &v );
  164.                     break;
  165.                 case 'l':
  166.                     bot_flag = TRUE;
  167.                     do_botleg( botleg, &v );
  168.                     break;
  169.                 case 'L':
  170.                     bot_flag = FALSE;
  171.                     cl_scr ( &v );
  172.                     if ( bor_flag ) bor_wndw( 0, 0, 23, W-1, &v );
  173.                     break;
  174.                 case '1':
  175.                     if ( jx < 10 ) jx++;
  176.                     break;
  177.                 case '2':
  178.                     if ( jx > 1 ) jx--;
  179.                     break;
  180.                 case 'a':
  181.                     if (numballs < MAXBALLS) {
  182.                         numballs++;
  183.                         o[numballs - 1].v = numballs;
  184.                     }
  185.                     break;
  186.                 case 'A':
  187.                     if (numballs > 1 ) numballs --;
  188.                     break;
  189.                 case 'g':
  190.                     bullet.y = 22;
  191.                     if ( bullet.x % 6 != 0 ) bullet.x++; else bullet.x-=5;
  192.                     break;
  193.             }
  194.         }
  195.  
  196.         for( i = 0; i < numballs; i++ ) {
  197.             o[i].h = jx;
  198.             o[i].w = 2*jx;
  199.             calc_next( &o[i] );
  200.             o_put( &o[i], &h[i], &v );
  201.         }
  202.         if ( bullet.y < 23 && bullet.y > 0 ) {
  203.             o_put( &bullet, &h[MAXBALLS], &v );
  204.         }
  205.         for( i = 0; i < numballs; i++ ) {
  206.             if ( (bullet.y>=o[i].y&&bullet.y<=o[i].y+o[i].h)&& \
  207.              (bullet.x>=o[i].x&&bullet.x<=o[i].x+o[i].w)) {
  208.                 printf( "\a" );
  209.                 o_clr( &o[i], &v );
  210.                 numballs--;
  211.                 for ( j = i; j < numballs; j++ ) {
  212.                 memcpy( &o[j], &o[j+1], sizeof( object_t ) );
  213.                 }
  214.             }
  215.         }
  216.         delay( t );
  217.         for( i = 0; i < numballs; i++ ) {
  218.             o_clr( &o[i], &v );
  219.         }
  220.         if ( bullet.y < 23 && bullet.y > 0 ) {
  221.             o_clr( &bullet, &v );
  222.             bullet.y--;
  223.         }
  224.         /*
  225.         o_unput( &h, &o, &v );
  226.         delay( t );
  227.         o_unput( &h2, &o2, &v );
  228.         */
  229.     }
  230.     /* close up shop */
  231.     set_vid_mode( v0.mode );
  232.     scr_restore( &v0, scr_buf );
  233.     crsr_pos_set( v0.crsr_row, v0.crsr_col, v0.page );
  234.  
  235.     return ch;
  236. }
  237. void o_put( object_t *o, object_t *h, vid_rec *v )
  238. {
  239.     char far *p;
  240.     char far *q;
  241.     int i,j,z;
  242.     char t;
  243.  
  244.     h->h = o->h;
  245.     h->w = o->w;
  246.     p = (char far *) &o->d[0];
  247.     q = (char far *) &h->d[0];
  248.  
  249.     for ( i = 0; i < o->h; i++ ) {
  250.         for (j = 0; j < o->w; j++ ) {
  251.             z = 160*(o->y + i) + 2*(o->x + j);
  252.             movedata(v->VIDEO_SEG, z, FP_SEG(q), FP_OFF(q)+i*o->w + j, 1);
  253.             t = h->d[i*o->w+j];
  254.             t = o->d[i*o->w + j];
  255.             if ( t ) {
  256.                 p = ( char far *) &t;
  257.                 movedata(FP_SEG(p),FP_OFF(p),v->VIDEO_SEG, z, 1);
  258.             }
  259.         }
  260.     }
  261. }
  262.  
  263. void o_clr( object_t *o, vid_rec *v )
  264. {
  265.     static char a[2] = { 0,7 };
  266.     char far *p;
  267.     int i,j,z;
  268.  
  269.     p = (char far *) &a[0];
  270.  
  271.     for ( i = 0; i < o->h; i++ ) {
  272.         for (j = 0; j < o->w; j++ ) {
  273.             z = 160*(o->y + i) + 2*(o->x + j);
  274.             movedata(FP_SEG(p),FP_OFF(p),v->VIDEO_SEG, z, 2);
  275.         }
  276.     }
  277. }
  278. void o_unput( object_t *h, object_t *o, vid_rec *v )
  279. {
  280.     char far *p;
  281.     int i,j;
  282.     char t;
  283.  
  284.     p = (char far *) &h->d[0];
  285.  
  286.     for ( i = 0; i < h->h; i++ ) {
  287.         for (j = 0; j < h->w; j++ ) {
  288.             t = h->d[i*h->w + j];
  289.             p = ( char far *) &t;
  290.             movedata(FP_SEG(p),FP_OFF(p),v->VIDEO_SEG,(o->y+i)*160+2*(o->x+j), 1);
  291.         }
  292.     }
  293. }
  294.  
  295. void delay ( int t )
  296. {
  297.     while ( t )
  298.         t--;
  299. }
  300.  
  301. void do_botleg( char *botleg, vid_rec *v )
  302. {
  303.     int k;
  304.     char ac[2];
  305.     char far *p;
  306.  
  307.     ac[0] = 32;
  308.     ac[1] = 'p';
  309.     p = &ac[0];
  310.     for ( k = 0; k < 80; k++ ) /* clear & rev. video the bot line of display */
  311.         movedata( FP_SEG( p ), FP_OFF( p ), v->VIDEO_SEG, 3840 + k*2, 2 );
  312.     p = &botleg[0];
  313.     for ( k = 0; k < strlen( botleg ); k++ ) /* put up the bot legend */
  314.         movedata( FP_SEG( p ), FP_OFF( p ) + k, v->VIDEO_SEG, 3840 + k*2, 1 );
  315. }
  316.  
  317. void calc_next( object_t *o )
  318. {
  319.     switch ( o->t ) {
  320.         case Se:
  321.             if ( ( o->x<W-o->w-o->v ) && ( o->y<24-o->h-1 ) ) {
  322.                 o->x+=o->v; o->y++;
  323.             }
  324.             else if ( ( o->x>=W-o->w-o->v ) && ( o->y>=24-o->h-1 ) ) {
  325.                 o->t = Nw; o->x-=o->v; o->y--;
  326.             }
  327.             else if ( o->x>=W-o->w-o->v ) {
  328.                 o->t = Sw; o->x-=o->v; o->y++;
  329.             }
  330.             else if ( o->y>=24-o->h-1 ) {
  331.                 o->t = Ne; o->x+=o->v; o->y--;
  332.             }
  333.             break;
  334.         case Ne:
  335.             if ( ( o->x<W-o->w-o->v ) && ( o->y>1 ) ) {
  336.                 o->x+=o->v; o->y--;
  337.             }
  338.             else if ( ( o->x>=W-o->w-o->v ) && ( o->y<=1 ) ) {
  339.                 o->t = Sw; o->x-=o->v; o->y++;
  340.             }
  341.             else if ( o->x>=W-o->w-o->v ) {
  342.                 o->t = Nw; o->x-=o->v; o->y--;
  343.             }
  344.             else if ( o->y<=1 ) {
  345.                 o->t = Se; o->x+=o->v; o->y++;
  346.             }
  347.             break;
  348.         case Nw:
  349.             if ( ( o->x>o->v ) && ( o->y>1 ) ) {
  350.                 o->x-=o->v; o->y--;